year_interval_end = case_when(
year == 2017L ~ 2020L,
year == 2020L ~ 2023L
)
) %>%
select(country, year = year_interval_end, gci_std)
shares_2014 <- un_indust_2015usd %>%
pivot_longer(
cols = c(
`Agriculture, hunting, forestry, fishing (ISIC A-B)`,
`Mining, Manufacturing, Utilities (ISIC C-E)`,
`Construction (ISIC F)`,
`Wholesale, retail trade, restaurants and hotels (ISIC G-H)`,
`Transport, storage and communication (ISIC I)`,
`Other Activities (ISIC J-P)`
),
names_to = "sector_raw",
values_to = "value"
) %>%
mutate(rz_sector = map_un_to_rz(sector_raw)) %>%
filter(year == 2014, !is.na(value), !is.na(rz_sector)) %>%
group_by(country) %>%
mutate(total_2014 = sum(value, na.rm = TRUE)) %>%
ungroup() %>%
mutate(share_2014 = value / total_2014) %>%
select(country, rz_sector, share_2014)
inc_sector_1416 <- incidents %>%
filter(Year %in% 2014:2016, !is.na(industry)) %>%
mutate(rz_sector = map_incidents_to_rz(industry)) %>%
filter(!is.na(rz_sector))
inc_us_sector_1416 <- usa_inc %>%
filter(Year %in% 2014:2023, !is.na(industry)) %>%
mutate(rz_sector = map_incidents_to_rz(industry)) %>%
filter(!is.na(rz_sector))
country_codes <- un_indust_2015usd %>% select(country, iso3c) %>% distinct()
income_classes <- class_df %>% select(Code, Income.group)
# ---- 7. EXPOSURE MEASURES ----
vulnerability_log <- inc_sector_1416 %>%
group_by(rz_sector) %>%
summarise(incidents_global = n(), .groups = "drop") %>%
mutate(vulnerability = as.numeric(scale(log1p(incidents_global)))) %>%
select(rz_sector, incidents_global, vulnerability)
vulnerability_us_log <- inc_us_sector_1416 %>%
group_by(rz_sector) %>%
summarise(incidents_us = n(), .groups = "drop") %>%
mutate(vulnerability = as.numeric(scale(log1p(incidents_us)))) %>%
select(rz_sector, incidents_us, vulnerability)
vuln_features <- inc_sector_1416 %>%
mutate(
is_crossborder = ifelse(!is.na(actor_country_code) & actor_country_code != country_code, 1L, 0L),
is_state_actor = ifelse(grepl("state|government|govt|military|APT|nation|intel", actor, ignore.case = TRUE), 1L, 0L),
is_ransom = ifelse(grepl("ransom", event_type, ignore.case = TRUE) | grepl("ransom", event_subtype, ignore.case = TRUE), 1L, 0L),
is_disruption = ifelse(
grepl("disruption|denial of service|dos|ddos|service outage|service disruption", event_type, ignore.case = TRUE) |
grepl("disruption|denial of service|dos|ddos|service outage|service disruption", event_subtype, ignore.case = TRUE),
1L, 0L
)
) %>%
group_by(rz_sector) %>%
summarise(
total_incidents = n(),
crossborder_incidents = sum(is_crossborder, na.rm = TRUE),
state_incidents = sum(is_state_actor, na.rm = TRUE),
ransom_incidents = sum(is_ransom, na.rm = TRUE),
disruption_incidents = sum(is_disruption, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
log_total = log1p(total_incidents),
share_cross = ifelse(total_incidents > 0, crossborder_incidents / total_incidents, 0),
share_state = ifelse(total_incidents > 0, state_incidents / total_incidents, 0),
share_ransom = ifelse(total_incidents > 0, ransom_incidents / total_incidents, 0),
share_disrupt = ifelse(total_incidents > 0, disruption_incidents / total_incidents, 0)
)
pca_input <- vuln_features %>% select(log_total, share_cross, share_state, share_disrupt) %>% as.matrix()
pca_res <- prcomp(pca_input, scale. = TRUE)
pc_scores <- as.data.frame(pca_res$x)
vulnerability_pca <- tibble(rz_sector = vuln_features$rz_sector, vulnerability = 0.7 * pc_scores[, 1] + 0.3 * pc_scores[, 2])
vuln_features_us <- inc_us_sector_1416 %>%
mutate(
is_crossborder = ifelse(!is.na(actor_country_code) & actor_country_code != country_code, 1L, 0L),
is_state_actor = ifelse(grepl("state|government|govt|military|APT|nation|intel", actor, ignore.case = TRUE), 1L, 0L),
is_ransom = ifelse(grepl("ransom", event_type, ignore.case = TRUE) | grepl("ransom", event_subtype, ignore.case = TRUE), 1L, 0L),
is_disruption = ifelse(
grepl("disruption|denial of service|dos|ddos|service outage|service disruption", event_type, ignore.case = TRUE) |
grepl("disruption|denial of service|dos|ddos|service outage|service disruption", event_subtype, ignore.case = TRUE),
1L, 0L
)
) %>%
group_by(rz_sector) %>%
summarise(
total_incidents = n(),
crossborder_incidents = sum(is_crossborder, na.rm = TRUE),
state_incidents = sum(is_state_actor, na.rm = TRUE),
ransom_incidents = sum(is_ransom, na.rm = TRUE),
disruption_incidents = sum(is_disruption, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
log_total = log1p(total_incidents),
share_cross = ifelse(total_incidents > 0, crossborder_incidents / total_incidents, 0),
share_state = ifelse(total_incidents > 0, state_incidents / total_incidents, 0),
share_ransom = ifelse(total_incidents > 0, ransom_incidents / total_incidents, 0),
share_disrupt = ifelse(total_incidents > 0, disruption_incidents / total_incidents, 0)
)
pca_input_us <- vuln_features_us %>% select(log_total, share_cross, share_state, share_disrupt) %>% as.matrix()
pca_res_us <- prcomp(pca_input_us, scale. = TRUE)
pc_scores_us <- as.data.frame(pca_res_us$x)
vulnerability_us_pca <- tibble(rz_sector = vuln_features_us$rz_sector, vulnerability = 0.7 * pc_scores_us[, 1] + 0.3 * pc_scores_us[, 2])
build_panel <- function(vulnerability_df) {
panel_longint <- va_wide %>%
left_join(shares_2014, by = c("country", "rz_sector")) %>%
left_join(vulnerability_df %>% select(rz_sector, vulnerability), by = "rz_sector") %>%
mutate(
log_va_2017 = log(va_2017),
log_va_2020 = log(va_2020),
log_va_2023 = log(va_2023),
growth_2020 = (log_va_2020 - log_va_2017) / 3,
growth_2023 = (log_va_2023 - log_va_2020) / 3
) %>%
select(country, rz_sector, share_2014, vulnerability, growth_2020, growth_2023) %>%
pivot_longer(cols = c(growth_2020, growth_2023), names_to = "year", values_to = "growth") %>%
mutate(year = ifelse(year == "growth_2020", 2020L, 2023L)) %>%
left_join(gci_for_panel, by = c("country", "year")) %>%
mutate(interact = vulnerability * gci_std) %>%
filter(!is.na(growth), !is.na(gci_std), !is.na(share_2014), !is.na(vulnerability)) %>%
left_join(country_codes, by = "country") %>%
left_join(income_classes, by = c("iso3c" = "Code")) %>%
mutate(hic = ifelse(Income.group == "High income", "HIC", "Non-HIC")) %>%
filter(!is.na(hic))
panel_5_all <- panel_longint %>% filter(rz_sector %in% rz5)
list(
all = panel_5_all,
hic = panel_5_all %>% filter(hic == "HIC"),
nonhic = panel_5_all %>% filter(hic == "Non-HIC")
)
}
panel_log <- build_panel(vulnerability_log)
panel_pca <- build_panel(vulnerability_pca)
panel_us_log <- build_panel(vulnerability_us_log)
panel_us_pca <- build_panel(vulnerability_us_pca)
# ---- 8. MAIN MODELS (original logic) ----
rz_log_all <- run_lm_rz(panel_log$all)
rz_log_hic <- run_lm_rz(panel_log$hic)
rz_log_nonhic <- run_lm_rz(panel_log$nonhic)
se_log_all <- se_clust(rz_log_all, panel_log$all)
se_log_hic <- se_clust(rz_log_hic, panel_log$hic)
se_log_nonhic <- se_clust(rz_log_nonhic, panel_log$nonhic)
d_log_all <- make_fixest_data(panel_log$all)
d_log_hic <- make_fixest_data(panel_log$hic)
d_log_nonhic <- make_fixest_data(panel_log$nonhic)
mfe_log_cs_y_all <- run_mfe_cs_y(d_log_all)
mfe_log_cs_y_hic <- run_mfe_cs_y(d_log_hic)
mfe_log_cs_y_nonhic <- run_mfe_cs_y(d_log_nonhic)
mfe_log_cs_cy_all <- run_mfe_cs_cy(d_log_all)
mfe_log_cs_cy_hic <- run_mfe_cs_cy(d_log_hic)
mfe_log_cs_cy_nonhic <- run_mfe_cs_cy(d_log_nonhic)
rz_us_log_all <- run_lm_rz(panel_us_log$all)
rz_us_log_hic <- run_lm_rz(panel_us_log$hic)
rz_us_log_nonhic <- run_lm_rz(panel_us_log$nonhic)
se_us_log_all <- se_clust(rz_us_log_all, panel_us_log$all)
se_us_log_hic <- se_clust(rz_us_log_hic, panel_us_log$hic)
se_us_log_nonhic <- se_clust(rz_us_log_nonhic, panel_us_log$nonhic)
d_us_log_all <- make_fixest_data(panel_us_log$all)
d_us_log_hic <- make_fixest_data(panel_us_log$hic)
d_us_log_nonhic <- make_fixest_data(panel_us_log$nonhic)
mfe_us_log_cs_y_all <- run_mfe_cs_y(d_us_log_all)
mfe_us_log_cs_y_hic <- run_mfe_cs_y(d_us_log_hic)
mfe_us_log_cs_y_nonhic <- run_mfe_cs_y(d_us_log_nonhic)
mfe_us_log_cs_cy_all <- run_mfe_cs_cy(d_us_log_all)
mfe_us_log_cs_cy_hic <- run_mfe_cs_cy(d_us_log_hic)
mfe_us_log_cs_cy_nonhic <- run_mfe_cs_cy(d_us_log_nonhic)
rz_us_pca_all <- run_lm_rz(panel_us_pca$all)
rz_us_pca_hic <- run_lm_rz(panel_us_pca$hic)
rz_us_pca_nonhic <- run_lm_rz(panel_us_pca$nonhic)
se_us_pca_all <- se_clust(rz_us_pca_all, panel_us_pca$all)
se_us_pca_hic <- se_clust(rz_us_pca_hic, panel_us_pca$hic)
se_us_pca_nonhic <- se_clust(rz_us_pca_nonhic, panel_us_pca$nonhic)
d_us_pca_all <- make_fixest_data(panel_us_pca$all)
d_us_pca_hic <- make_fixest_data(panel_us_pca$hic)
d_us_pca_nonhic <- make_fixest_data(panel_us_pca$nonhic)
mfe_us_pca_cs_y_all <- run_mfe_cs_y(d_us_pca_all)
mfe_us_pca_cs_y_hic <- run_mfe_cs_y(d_us_pca_hic)
mfe_us_pca_cs_y_nonhic <- run_mfe_cs_y(d_us_pca_nonhic)
mfe_us_pca_cs_cy_all <- run_mfe_cs_cy(d_us_pca_all)
mfe_us_pca_cs_cy_hic <- run_mfe_cs_cy(d_us_pca_hic)
mfe_us_pca_cs_cy_nonhic <- run_mfe_cs_cy(d_us_pca_nonhic)
rz_pca_all <- run_lm_rz(panel_pca$all)
rz_pca_hic <- run_lm_rz(panel_pca$hic)
rz_pca_nonhic <- run_lm_rz(panel_pca$nonhic)
se_pca_all <- se_clust(rz_pca_all, panel_pca$all)
se_pca_hic <- se_clust(rz_pca_hic, panel_pca$hic)
se_pca_nonhic <- se_clust(rz_pca_nonhic, panel_pca$nonhic)
d_pca_all <- make_fixest_data(panel_pca$all)
d_pca_hic <- make_fixest_data(panel_pca$hic)
d_pca_nonhic <- make_fixest_data(panel_pca$nonhic)
mfe_pca_cs_y_all <- run_mfe_cs_y(d_pca_all)
mfe_pca_cs_y_hic <- run_mfe_cs_y(d_pca_hic)
mfe_pca_cs_y_nonhic <- run_mfe_cs_y(d_pca_nonhic)
mfe_pca_cs_cy_all <- run_mfe_cs_cy(d_pca_all)
mfe_pca_cs_cy_hic <- run_mfe_cs_cy(d_pca_hic)
mfe_pca_cs_cy_nonhic <- run_mfe_cs_cy(d_pca_nonhic)
# ---- 9. IO MODEL (original logic) ----
io_rz <- io_digital %>% mutate(rz_sector = map_io_to_rz(sector_description)) %>% filter(rz_sector %in% rz5)
io_exposure <- io_rz %>%
filter(year %in% 2014:2016) %>%
group_by(rz_sector) %>%
summarise(
exposure_io = mean(digital_input_share, na.rm = TRUE),
digital_share_median = median(digital_input_share, na.rm = TRUE),
digital_sharey_mean = mean(digital_input_share_y, na.rm = TRUE),
n_countries = n_distinct(ccode),
n_obs = n(),
.groups = "drop"
) %>%
mutate(vulnerability = as.numeric(scale(exposure_io)))
panel_io <- build_panel(io_exposure)
rz_io_all <- run_lm_rz(panel_io$all)
rz_io_hic <- run_lm_rz(panel_io$hic)
rz_io_nonhic <- run_lm_rz(panel_io$nonhic)
se_io_all <- se_clust(rz_io_all, panel_io$all)
se_io_hic <- se_clust(rz_io_hic, panel_io$hic)
se_io_nonhic <- se_clust(rz_io_nonhic, panel_io$nonhic)
d_io_all <- make_fixest_data(panel_io$all)
d_io_hic <- make_fixest_data(panel_io$hic)
d_io_nonhic <- make_fixest_data(panel_io$nonhic)
mfe_io_cs_y_all <- run_mfe_cs_y(d_io_all)
mfe_io_cs_y_hic <- run_mfe_cs_y(d_io_hic)
mfe_io_cs_y_nonhic <- run_mfe_cs_y(d_io_nonhic)
mfe_io_cs_cy_all <- run_mfe_cs_cy(d_io_all)
mfe_io_cs_cy_hic <- run_mfe_cs_cy(d_io_hic)
mfe_io_cs_cy_nonhic <- run_mfe_cs_cy(d_io_nonhic)
# ---- 10. TABLE 6 descriptive stats (original logic) ----
vars_core <- c("growth", "share_2014", "gci_std", "vulnerability", "interact")
sample_all <- panel_log$all %>%
dplyr::select(country, rz_sector, year, hic, dplyr::all_of(vars_core)) %>%
dplyr::mutate(sample = "All")
sample_hic <- panel_log$hic %>%
dplyr::select(country, rz_sector, year, hic, dplyr::all_of(vars_core)) %>%
dplyr::mutate(sample = "HIC")
sample_nonhic <- panel_log$nonhic %>%
dplyr::select(country, rz_sector, year, hic, dplyr::all_of(vars_core)) %>%
dplyr::mutate(sample = "Non-HIC")
df_desc <- dplyr::bind_rows(sample_all, sample_hic, sample_nonhic)
desc_univariate <- function(x) {
x <- x[is.finite(x)]
tibble::tibble(
N = length(x),
Mean = mean(x),
SD = sd(x),
Min = min(x),
P01 = as.numeric(stats::quantile(x, 0.01, na.rm = TRUE)),
P05 = as.numeric(stats::quantile(x, 0.05, na.rm = TRUE)),
P50 = as.numeric(stats::quantile(x, 0.50, na.rm = TRUE)),
P95 = as.numeric(stats::quantile(x, 0.95, na.rm = TRUE)),
P99 = as.numeric(stats::quantile(x, 0.99, na.rm = TRUE)),
Max = max(x)
)
}
table6_df <- df_desc %>%
tidyr::pivot_longer(
cols = dplyr::all_of(vars_core),
names_to = "variable",
values_to = "value"
) %>%
dplyr::group_by(sample, variable) %>%
dplyr::summarise(desc_univariate(value), .groups = "drop") %>%
dplyr::mutate(
Variable = dplyr::case_when(
variable == "growth" ~ "Annualized VA growth",
variable == "share_2014" ~ "Share 2014",
variable == "gci_std" ~ "GCI (standardized)",
variable == "vulnerability" ~ "Vulnerability (log incidents)",
variable == "interact" ~ "Interaction",
TRUE ~ variable
)
) %>%
dplyr::select(sample, Variable, N, Mean, SD, Min, P01, P05, P50, P95, P99, Max) %>%
dplyr::arrange(
factor(sample, levels = c("All", "HIC", "Non-HIC")),
factor(
Variable,
levels = c(
"Annualized VA growth",
"Share 2014",
"GCI (standardized)",
"Vulnerability (log incidents)",
"Interaction"
)
)
)
write_xlsx_single(
table6_df,
"Table_6_Appendix_Descriptive_statistics_by_income_group.xlsx"
)
# ---- 11. TABLE 4 placebo (preserve original placebo block logic from uploaded snippet) ----
panel_base <- va_wide %>%
filter(country != "USA") %>%
left_join(shares_2014, by = c("country", "rz_sector")) %>%
mutate(
log_va_2017 = log(va_2017),
log_va_2020 = log(va_2020),
log_va_2023 = log(va_2023),
growth_2020 = (log_va_2020 - log_va_2017) / (2020 - 2017),
growth_2023 = (log_va_2023 - log_va_2020) / (2023 - 2020)
) %>%
select(country, rz_sector, share_2014, growth_2020, growth_2023) %>%
pivot_longer(
cols = c(growth_2020, growth_2023),
names_to = "year",
values_to = "growth"
) %>%
mutate(year = ifelse(year == "growth_2020", 2020L, 2023L)) %>%
left_join(gci_for_panel, by = c("country", "year")) %>%
filter(!is.na(growth), !is.na(gci_std), !is.na(share_2014))
panel_base <- panel_base %>%
left_join(country_codes, by = "country") %>%
left_join(class_df %>% select(Code, Income.group), by = c("iso3c" = "Code")) %>%
mutate(hic = ifelse(Income.group == "High income", "HIC", "Non-HIC")) %>%
filter(!is.na(hic))
panel_base_5 <- panel_base %>% filter(rz_sector %in% rz5)
energy_long <- energyinput %>%
rename(industry_desc = `Industry Description`) %>%
pivot_longer(cols = matches("^[0-9]{4}$"), names_to = "year", values_to = "energy_index") %>%
mutate(
year = as.integer(year),
industry_desc = as.character(industry_desc),
energy_index = as.numeric(energy_index)
) %>%
filter(!is.na(year), !is.na(energy_index), !is.na(industry_desc))
energy_1416 <- energy_long %>%
filter(year %in% 2014:2016) %>%
group_by(industry_desc) %>%
summarise(energy_1416 = mean(energy_index, na.rm = TRUE), .groups = "drop")
energy_placebo_sector <- energy_1416 %>%
mutate(
rz_sector = case_when(
industry_desc %in% c("Farms", "Forestry, fishing, and related activities") ~ "Agriculture",
industry_desc == "Construction" ~ "Construction",
industry_desc %in% c(
"Oil and gas extraction", "Mining, except oil and gas", "Support activities for mining",
"Utilities", "Wood products", "Nonmetallic mineral products", "Primary metals",
"Fabricated metal products", "Machinery", "Computer and electronic products",
"Electrical equipment, appliances, and components", "Motor vehicles, bodies and trailers, and parts",
"Other transportation equipment", "Furniture and related products", "Miscellaneous manufacturing",
"Food and beverage and tobacco products", "Textile mills and textile product mills",
"Apparel and leather and allied products", "Paper products", "Printing and related support activities",
"Petroleum and coal products", "Chemical products", "Plastics and rubber products"
) ~ "Industry",
industry_desc %in% c(
"Wholesale trade", "Retail trade", "Accommodation", "Food services and drinking places"
) ~ "Trade_Hospitality",
industry_desc %in% c(
"Air transportation", "Rail transportation", "Water transportation",
"Truck transportation", "Transit and ground passenger transportation",
"Pipeline transportation", "Other transportation and support activities",
"Warehousing and storage", "Broadcasting and telecommunications"
) ~ "Transport_Communications",
TRUE ~ "Other_Services"
)
) %>%
group_by(rz_sector) %>%
summarise(energy_placebo = mean(energy_1416, na.rm = TRUE), .groups = "drop") %>%
mutate(placebo_vuln = as.numeric(scale(energy_placebo))) %>%
select(rz_sector, placebo_vuln)
energy_placebo_sector <- energy_placebo_sector %>%
filter(rz_sector %in% unique(panel_base_5$rz_sector))
panel_placebo_5 <- panel_base_5 %>%
left_join(energy_placebo_sector, by = "rz_sector") %>%
mutate(interact_placebo = placebo_vuln * gci_std) %>%
filter(!is.na(placebo_vuln), !is.na(interact_placebo))
run_rz_placebo <- function(data) {
f <- growth ~ share_2014 + interact_placebo + factor(country) + factor(rz_sector)
if (dplyr::n_distinct(data$year) > 1L) f <- update(f, . ~ . + factor(year))
lm(f, data = data)
}
d_all <- panel_placebo_5
d_hic <- panel_placebo_5 %>% filter(hic == "HIC")
d_nhic <- panel_placebo_5 %>% filter(hic == "Non-HIC")
m_all <- run_rz_placebo(d_all)
m_hic <- run_rz_placebo(d_hic)
m_nhic <- run_rz_placebo(d_nhic)
se_all <- se_clust(m_all, d_all)
se_hic <- se_clust(m_hic, d_hic)
se_nhic <- se_clust(m_nhic, d_nhic)
# ---- 12. TABLE 5 leave-one-sector-out (original uploaded snippet logic) ----
rz_sectors <- rz5
run_mfe_loso <- function(data) {
feols(
growth ~ interact | country^rz_sector + country^year,
data = data,
cluster = ~country
)
}
m_base <- run_mfe_loso(panel_log$all)
m_loso_agri <- run_mfe_loso(panel_log$all %>% filter(rz_sector != "Agriculture"))
m_loso_ind <- run_mfe_loso(panel_log$all %>% filter(rz_sector != "Industry"))
m_loso_cons <- run_mfe_loso(panel_log$all %>% filter(rz_sector != "Construction"))
m_loso_trade <- run_mfe_loso(panel_log$all %>% filter(rz_sector != "Trade_Hospitality"))
m_loso_trans <- run_mfe_loso(panel_log$all %>% filter(rz_sector != "Transport_Communications"))
# ---- 13. Build tables and export XLSX ----
# Table 1
n_incidents_global_5 <- nrow(inc_sector_1416 %>% filter(rz_sector %in% rz5))
n_incidents_us_5 <- nrow(inc_us_sector_1416 %>% filter(rz_sector %in% rz5))
table1_df <- vulnerability_log %>%
left_join(vulnerability_pca %>% rename(global_pca = vulnerability), by = "rz_sector") %>%
left_join(io_exposure %>% select(rz_sector, exposure_io), by = "rz_sector") %>%
left_join(vulnerability_us_log %>% select(rz_sector, incidents_us), by = "rz_sector") %>%
left_join(vulnerability_us_pca %>% rename(us_pca = vulnerability), by = "rz_sector") %>%
filter(rz_sector %in% rz5) %>%
transmute(
Sector = pretty_sector(rz_sector),
Global_Incidents = incidents_global,
Global_PCA = round(global_pca, 3),
Digital_Input_Mean = round(exposure_io, 3),
US_Incidents = incidents_us,
US_PCA = round(us_pca, 3)
) %>%
arrange(match(Sector, c(
"Transport and Communications",
"Trade and Hospitality",
"Industry",
"Construction",
"Agriculture"
)))
write_xlsx_single(table1_df, "Table_1_Sectoral_exposure_measures.xlsx")
# Table 2
model_names_t2 <- c("Baseline", "IO_digital_exposure", "US_based_vulnerability")
table2_df <- bind_rows(
extract_fixest_term(mfe_log_cs_cy_all, model_names_t2[1]),
extract_fixest_term(mfe_io_cs_cy_all, model_names_t2[2]),
extract_fixest_term(mfe_us_log_cs_cy_all, model_names_t2[3])
)
table2_df$Countries <- n_distinct(panel_log$all$country)
table2_df$Cyber_Incidents <- c(n_incidents_global_5, NA, n_incidents_us_5)
write_xlsx_single(table2_df, "Table_2_Main_results_global_sample.xlsx")
# Table 3
table3_df <- bind_rows(
extract_fixest_term(mfe_log_cs_cy_hic, "HIC_Baseline"),
extract_fixest_term(mfe_io_cs_cy_hic, "HIC_IO"),
extract_fixest_term(mfe_us_log_cs_cy_hic, "HIC_US_based"),
extract_fixest_term(mfe_log_cs_cy_nonhic, "Non_HIC_Baseline"),
extract_fixest_term(mfe_io_cs_cy_nonhic, "Non_HIC_IO"),
extract_fixest_term(mfe_us_log_cs_cy_nonhic, "Non_HIC_US_based")
)
table3_df$Countries <- c(
n_distinct(panel_log$hic$country), n_distinct(panel_io$hic$country), n_distinct(panel_us_log$hic$country),
n_distinct(panel_log$nonhic$country), n_distinct(panel_io$nonhic$country), n_distinct(panel_us_log$nonhic$country)
)
table3_df$Country_Sector_FE <- c(
dplyr::n_distinct(interaction(panel_log$hic$country, panel_log$hic$rz_sector, drop = TRUE)),
dplyr::n_distinct(interaction(panel_io$hic$country, panel_io$hic$rz_sector, drop = TRUE)),
dplyr::n_distinct(interaction(panel_us_log$hic$country, panel_us_log$hic$rz_sector, drop = TRUE)),
dplyr::n_distinct(interaction(panel_log$nonhic$country, panel_log$nonhic$rz_sector, drop = TRUE)),
dplyr::n_distinct(interaction(panel_io$nonhic$country, panel_io$nonhic$rz_sector, drop = TRUE)),
dplyr::n_distinct(interaction(panel_us_log$nonhic$country, panel_us_log$nonhic$rz_sector, drop = TRUE))
)
table3_df$Country_Year_FE <- c(
dplyr::n_distinct(interaction(panel_log$hic$country, panel_log$hic$year, drop = TRUE)),
dplyr::n_distinct(interaction(panel_io$hic$country, panel_io$hic$year, drop = TRUE)),
dplyr::n_distinct(interaction(panel_us_log$hic$country, panel_us_log$hic$year, drop = TRUE)),
dplyr::n_distinct(interaction(panel_log$nonhic$country, panel_log$nonhic$year, drop = TRUE)),
dplyr::n_distinct(interaction(panel_io$nonhic$country, panel_io$nonhic$year, drop = TRUE)),
dplyr::n_distinct(interaction(panel_us_log$nonhic$country, panel_us_log$nonhic$year, drop = TRUE))
)
write_xlsx_single(table3_df, "Table_3_Main_results_income_groups.xlsx")
# Table 4
table4_df <- bind_rows(
extract_lm_term(m_all, se_all, "All_countries", "interact_placebo"),
extract_lm_term(m_hic, se_hic, "HIC", "interact_placebo"),
extract_lm_term(m_nhic, se_nhic, "Non_HIC", "interact_placebo")
)
write_xlsx_single(table4_df, "Table_4_Placebo_test_energy_input_intensity.xlsx")
# Table 5
table5_df <- bind_rows(
extract_fixest_term(m_base, "Baseline"),
extract_fixest_term(m_loso_agri, "Drop_Agriculture"),
extract_fixest_term(m_loso_ind, "Drop_Industry"),
extract_fixest_term(m_loso_cons, "Drop_Construction"),
extract_fixest_term(m_loso_trade, "Drop_Trade_Hospitality"),
extract_fixest_term(m_loso_trans, "Drop_Transport_Communications")
)
write_xlsx_single(table5_df, "Table_5_Leave_one_sector_out_robustness.xlsx")
# Table 6 Appendix
#Already exported
# Table 7 Appendix: Global PCA models (baseline PCA and US PCA)
table7_df <- bind_rows(
extract_fixest_term(mfe_pca_cs_cy_all, "Baseline_PCA"),
extract_fixest_term(mfe_us_pca_cs_cy_all, "US_based_PCA")
)
table7_df$Countries <- n_distinct(panel_pca$all$country)
table7_df$Cyber_Incidents <- c(n_incidents_global_5, n_incidents_us_5)
write_xlsx_single(table7_df, "Table_7_Appendix_Global_models_with_PCA.xlsx")
# Table 8 Appendix: separate fixed effects global models
table8_df <- bind_rows(
extract_lm_term(rz_log_all, se_log_all, "Baseline", "interact"),
extract_lm_term(rz_io_all, se_io_all, "IO_digital_exposure", "interact"),
extract_lm_term(rz_us_log_all, se_us_log_all, "US_based_vulnerability", "interact")
)
# add share(2014) coefficient from same models
share_rows <- bind_rows(
extract_lm_term(rz_log_all, se_log_all, "Baseline", "share_2014"),
extract_lm_term(rz_io_all, se_io_all, "IO_digital_exposure", "share_2014"),
extract_lm_term(rz_us_log_all, se_us_log_all, "US_based_vulnerability", "share_2014")
)
table8_df <- bind_rows(share_rows, table8_df)
write_xlsx_single(table8_df, "Table_8_Appendix_Global_models_with_separate_fixed_effects.xlsx")
message("Done. Exported standalone XLSX tables to: ", tables_dir)
install.packages("renv")
renv::init()
renv::snapshot(prune = TRUE)
renv::snapshot()
